#ifndef __LEGACY_OBJECT_SERVER_HPP
#define __LEGACY_OBJECT_SERVER_HPP

#include <fibre/base_types.hpp>
#include <fibre/bufchain.hpp>
#include <fibre/bufptr.hpp>
#include <fibre/callback.hpp>
#include <fibre/rich_status.hpp>
#include <fibre/status.hpp>
#include <stdint.h>
#include <stdlib.h>

namespace fibre {

class Domain;

struct LegacyObjectServer {
    uint8_t rx_buf_[128];
    size_t rx_pos_;
    uint8_t tx_buf_[128];
    size_t tx_pos_;
    size_t expected_ep_ = 0;  // 0 while no call in progress
    size_t trigger_ep_;
    size_t n_inputs_;
    size_t n_outputs_;
    size_t output_size_;

    uint8_t call_state_[256];

    void reset() {
        rx_pos_ = 0;
        tx_pos_ = 0;
        expected_ep_ = 0;
        trigger_ep_ = 0;
        n_inputs_ = 0;
        n_outputs_ = 0;
        output_size_ = 0;
    }

    RichStatus endpoint_handler(Domain* domain, int idx,
                                cbufptr_t* input_buffer,
                                bufptr_t* output_buffer);
};

enum class EndpointType {
    kFunctionTrigger,
    kFunctionInput,
    kFunctionOutput,
    kRoProperty,
    kRwProperty,
};

struct EndpointDefinition {
    EndpointType type;
    union {
        struct {
            ServerFunctionId function_id;
            ServerObjectId object_id;
        } function_trigger;
        struct {
            unsigned size;
        } function_input;
        struct {
            unsigned size;
        } function_output;
        struct {
            ServerFunctionId read_function_id;
            ServerObjectId object_id;
        } ro_property;
        struct {
            ServerFunctionId read_function_id;
            ServerFunctionId exchange_function_id;
            ServerObjectId object_id;
        } rw_property;
    };
};

// Defined in autogenerated endpoints.cpp
extern const unsigned char embedded_json[];
extern const size_t embedded_json_length;
extern EndpointDefinition endpoint_table[];
extern const uint16_t json_crc_;
extern const uint32_t json_version_id_;
extern const size_t n_endpoints;

}  // namespace fibre

#endif  // __LEGACY_OBJECT_SERVER_HPP
